#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define	SIMPLE_CHOICE 0
#define ION_CHOICE 1
#define SQUARE_MODE 0
#define LIST_MODE 1
#define MAX_CHAR_PER_ROW 2000

int main (int argc, const char * argv[]) {
	const char* square = "Square";
	const char* list = "List";
	const char* simple = "Simple";
	
	//Dati per la matrice (inizializzazione iniziale)
	unsigned int rows = 3;
	unsigned int columns = 3;
	unsigned int mode = SQUARE_MODE;
	unsigned int choice = SIMPLE_CHOICE;
	
	//Dati per la gestione dell'inizio (inizializzazione iniziale)
	unsigned int starting_row = 0;
	unsigned int ending_row = 0;
	unsigned int starting_column = 0;
	unsigned int ending_column = 0;
	
	if (argc == 9) {
		choice = (strcmp(argv[1], simple) == 0)?(SIMPLE_CHOICE):(ION_CHOICE);
		rows = atoi(argv[2]);
		columns = atoi(argv[3]);
		mode = (strcmp(argv[4], square) == 0)?(SQUARE_MODE):((strcmp(argv[4], list) == 0)?(LIST_MODE):(-1));
		starting_row = atoi(argv[5]);
		ending_row = atoi(argv[6]);
		starting_column = atoi(argv[7]);
		ending_column = atoi(argv[8]);
	 
	} else {
		printf("TissueManager <Simple | Ion > <rows> <columns> <Square | List> <starting stimulus row> <ending stimulus row> <starting stimulus columns> <ending stimulus columns>.\n");
		exit(1);
	}
	
	if (mode != LIST_MODE && mode != SQUARE_MODE && choice != SIMPLE_CHOICE && choice != ION_CHOICE ) {
		printf("Tissue configuration or choice wrong.");
		exit(1);
	}
	
	unsigned int i, j;
	FILE *filebk;
	FILE *filesim;
	
	filebk = fopen("tessuto.bk", "w");
	
	if ( filebk == NULL) {
		printf("Impossible opening/creating .bk file!");
		exit(1);
	} else if (choice == SIMPLE_CHOICE) {
		if(mode == SQUARE_MODE) {
			fprintf(filebk, "bio\n\nlocalities:\nlogical self;\nlogical next_1;\nlogical next_2;\nlogical next_3;\nlogical next_4;\nlogical next_5;\nlogical next_6;\nlogical next_7;\nlogical next_8;\n");
			
			for (i = 0; i < rows; ++i) {
				for (j = 0; j < columns; ++j) {
					fprintf(filebk, "physical cell_%d_%d;\n", i, j);
				}
			}
			fprintf(filebk, "\nenvironments:\n");
			
			char* n1 = malloc(sizeof(char) * MAX_CHAR_PER_ROW);
			char* n2 = malloc(sizeof(char) * MAX_CHAR_PER_ROW);
			char* n3 = malloc(sizeof(char) * MAX_CHAR_PER_ROW);
			char* n4 = malloc(sizeof(char) * MAX_CHAR_PER_ROW);
			char* n5 = malloc(sizeof(char) * MAX_CHAR_PER_ROW);
			char* n6 = malloc(sizeof(char) * MAX_CHAR_PER_ROW);
			char* n7 = malloc(sizeof(char) * MAX_CHAR_PER_ROW);
			char* n8 = malloc(sizeof(char) * MAX_CHAR_PER_ROW);
			
			for (i = 0; i < rows; ++i) {
				for (j = 0; j < columns; ++j) {
					sprintf(n1, "next_1 -> cell_%d_%d", (i-1), j);
					sprintf(n2, "next_2 -> cell_%d_%d", (i-1), (j+1));
					sprintf(n3, "next_3 -> cell_%d_%d", i, (j+1));
					sprintf(n4, "next_4 -> cell_%d_%d", (i+1), (j+1));
					sprintf(n5, "next_5 -> cell_%d_%d", (i+1), j);
					sprintf(n6, "next_6 -> cell_%d_%d", (i+1), (j-1));
					sprintf(n7, "next_7 -> cell_%d_%d", i, (j-1));
					sprintf(n8, "next_8 -> cell_%d_%d", (i-1), (j-1));

					
					if(i == 0 && j == 0) {
						fprintf(filebk, "cell_%d_%d: [self -> cell_%d_%d, %s, %s, %s];\n", i, j, i, j, n3, n4, n5);
					} else if(i == 0 && j == (columns - 1)) {
						fprintf(filebk, "cell_%d_%d: [self -> cell_%d_%d, %s, %s, %s];\n", i, j, i, j, n5, n6, n7);
					} else if(i == 0) {
						fprintf(filebk, "cell_%d_%d: [self -> cell_%d_%d, %s, %s, %s, %s, %s];\n", i, j, i, j, n3, n4, n5, n6, n7);
					} else if(i == (rows - 1) && j == 0) {
						fprintf(filebk, "cell_%d_%d: [self -> cell_%d_%d, %s, %s, %s];\n", i, j, i, j, n1, n2, n3);
					} else if(i == (rows - 1) && j == (columns - 1)) {
						fprintf(filebk, "cell_%d_%d: [self -> cell_%d_%d, %s, %s, %s];\n", i, j, i, j, n1, n7, n8);
					} else if(i == (rows - 1)) {
						fprintf(filebk, "cell_%d_%d: [self -> cell_%d_%d, %s, %s, %s, %s, %s];\n", i, j, i, j, n1, n2, n3, n7, n8);
					} else if(j == 0) {
						fprintf(filebk, "cell_%d_%d: [self -> cell_%d_%d, %s, %s, %s, %s, %s];\n", i, j, i, j, n1, n2, n3, n4, n5);
					} else if(j == (columns - 1)) {
						fprintf(filebk, "cell_%d_%d: [self -> cell_%d_%d, %s, %s, %s, %s, %s];\n", i, j, i, j, n1, n5, n6, n7, n8);
					} else {
						fprintf(filebk, "cell_%d_%d: [self -> cell_%d_%d, %s, %s, %s, %s, %s, %s, %s, %s];\n", i, j, i, j, n1, n2, n3, n4, n5, n6, n7, n8);
					}
				}
			}
			
			free(n1);
			free(n2);
			free(n3);
			free(n4);
			free(n5);
			free(n6);
			free(n7);
			free(n8);
			
			n1 = NULL;
			n2 = NULL;
			n3 = NULL;
			n4 = NULL;
			n5 = NULL;
			n6 = NULL;
			n7 = NULL;
			n8 = NULL;
			
			fprintf(filebk, "\nmessages: Ddp, Signal, Stimulated, Excited, Ignore;\n\nagents:\n");
			
			for (i = 0; i < rows; ++i) {
				for (j = 0; j < columns; ++j) {
					if(i == 0 && j == 0) {
						fprintf(filebk, 
								"let CellAgent_%d_%d be \n  X -> in( Signal )@self:1.0.[Stimulated] | [Ignore] | X1 \n \n  X1 -> {[Ignore]@cell_%d_%d => 1.0} in( Signal )@self:100000.0.X1 \n    + {[Ddp]@cell_%d_%d < 160.0 && [Stimulated]@cell_%d_%d => 1.0} read( Ddp )@self:0.12.[Ddp] | X1 \n    + {[Ddp]@cell_%d_%d => 160.0 && [Stimulated]@cell_%d_%d => 1.0} in( Stimulated )@self:1.0.[Excited] | [Signal]@next_3 | [Signal]@next_4 | [Signal]@next_5 | X1 \n    + {[Ddp]@cell_%d_%d => 40.0 && [Stimulated]@cell_%d_%d <= 0.0 && [Excited]@cell_%d_%d => 1.0} in( Ddp )@self:0.12.X1 \n    + {[Ddp]@cell_%d_%d < 40.0 && [Stimulated]@cell_%d_%d <= 0.0} out( Ddp )@self:1.0.X2 \n	\n  X2 -> {[Ignore]@cell_%d_%d => 1.0} in( Signal )@self:10000000.0.X2 \n    + {[Ddp]@cell_%d_%d < 60.0} out( Ddp )@self:1.0.[Ddp] | X2 \n    + {[Ddp]@cell_%d_%d => 60.0} in( Ddp | Excited | Ignore )@self:1.0.[Ddp] | X \nend \n \n", 
								i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j);
					} else if(i == 0 && j == (columns - 1)) {
						fprintf(filebk, 
								"let CellAgent_%d_%d be \n  X -> in( Signal )@self:1.0.[Stimulated] | [Ignore] | X1 \n \n  X1 -> {[Ignore]@cell_%d_%d => 1.0} in( Signal )@self:100000.0.X1 \n    + {[Ddp]@cell_%d_%d < 160.0 && [Stimulated]@cell_%d_%d => 1.0} read( Ddp )@self:0.12.[Ddp] | X1 \n    + {[Ddp]@cell_%d_%d => 160.0 && [Stimulated]@cell_%d_%d => 1.0} in( Stimulated )@self:1.0.[Excited] | [Signal]@next_5 | [Signal]@next_6 | [Signal]@next_7 | X1 \n    + {[Ddp]@cell_%d_%d => 40.0 && [Stimulated]@cell_%d_%d <= 0.0 && [Excited]@cell_%d_%d => 1.0} in( Ddp )@self:0.12.X1 \n    + {[Ddp]@cell_%d_%d < 40.0 && [Stimulated]@cell_%d_%d <= 0.0} out( Ddp )@self:1.0.X2 \n \n  X2 -> {[Ignore]@cell_%d_%d => 1.0} in( Signal )@self:10000000.0.X2 \n    + {[Ddp]@cell_%d_%d < 60.0} out( Ddp )@self:1.0.[Ddp] | X2 \n    + {[Ddp]@cell_%d_%d => 60.0} in( Ddp | Excited | Ignore )@self:1.0.[Ddp] | X \nend \n \n", 
								
								i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j);
					} else if(i == 0) {
						fprintf(filebk, 
								"let CellAgent_%d_%d be \n  X -> in( Signal )@self:1.0.[Stimulated] | [Ignore] | X1 \n \n  X1 -> {[Ignore]@cell_%d_%d => 1.0} in( Signal )@self:100000.0.X1 \n    + {[Ddp]@cell_%d_%d < 160.0 && [Stimulated]@cell_%d_%d => 1.0} read( Ddp )@self:0.12.[Ddp] | X1 \n    + {[Ddp]@cell_%d_%d => 160.0 && [Stimulated]@cell_%d_%d => 1.0} in( Stimulated )@self:1.0.[Excited] | [Signal]@next_3 | [Signal]@next_4 | [Signal]@next_5 | [Signal]@next_6 | [Signal]@next_7 | X1 \n    + {[Ddp]@cell_%d_%d => 40.0 && [Stimulated]@cell_%d_%d <= 0.0 && [Excited]@cell_%d_%d => 1.0} in( Ddp )@self:0.12.X1 \n    + {[Ddp]@cell_%d_%d < 40.0 && [Stimulated]@cell_%d_%d <= 0.0} out( Ddp )@self:1.0.X2 \n \n  X2 -> {[Ignore]@cell_%d_%d => 1.0} in( Signal )@self:10000000.0.X2 \n    + {[Ddp]@cell_%d_%d < 60.0} out( Ddp )@self:1.0.[Ddp] | X2 \n    + {[Ddp]@cell_%d_%d => 60.0} in( Ddp | Excited | Ignore )@self:1.0.[Ddp] | X \nend \n \n", 
								
								i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j);
					} else if(i == (rows - 1) && j == 0) {
						fprintf(filebk, 
								"let CellAgent_%d_%d be \n  X -> in( Signal )@self:1.0.[Stimulated] | [Ignore] | X1 \n \n  X1 -> {[Ignore]@cell_%d_%d => 1.0} in( Signal )@self:100000.0.X1 \n    + {[Ddp]@cell_%d_%d < 160.0 && [Stimulated]@cell_%d_%d => 1.0} read( Ddp )@self:0.12.[Ddp] | X1 \n    + {[Ddp]@cell_%d_%d => 160.0 && [Stimulated]@cell_%d_%d => 1.0} in( Stimulated )@self:1.0.[Excited] | [Signal]@next_1 | [Signal]@next_2 | [Signal]@next_3 | X1 \n    + {[Ddp]@cell_%d_%d => 40.0 && [Stimulated]@cell_%d_%d <= 0.0 && [Excited]@cell_%d_%d => 1.0} in( Ddp )@self:0.12.X1 \n    + {[Ddp]@cell_%d_%d < 40.0 && [Stimulated]@cell_%d_%d <= 0.0} out( Ddp )@self:1.0.X2 \n \n  X2 -> {[Ignore]@cell_%d_%d => 1.0} in( Signal )@self:10000000.0.X2 \n    + {[Ddp]@cell_%d_%d < 60.0} out( Ddp )@self:1.0.[Ddp] | X2 \n    + {[Ddp]@cell_%d_%d => 60.0} in( Ddp | Excited | Ignore )@self:1.0.[Ddp] | X \nend \n \n", 
								
								i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j);
					} else if(i == (rows - 1) && j == (columns - 1)) {
						fprintf(filebk, 
								"let CellAgent_%d_%d be \n  X -> in( Signal )@self:1.0.[Stimulated] | [Ignore] | X1 \n \n  X1 -> {[Ignore]@cell_%d_%d => 1.0} in( Signal )@self:100000.0.X1 \n    + {[Ddp]@cell_%d_%d < 160.0 && [Stimulated]@cell_%d_%d => 1.0} read( Ddp )@self:0.12.[Ddp] | X1 \n    + {[Ddp]@cell_%d_%d => 160.0 && [Stimulated]@cell_%d_%d => 1.0} in( Stimulated )@self:1.0.[Excited] | [Signal]@next_1 | [Signal]@next_7 | [Signal]@next_8 | X1 \n    + {[Ddp]@cell_%d_%d => 40.0 && [Stimulated]@cell_%d_%d <= 0.0 && [Excited]@cell_%d_%d => 1.0} in( Ddp )@self:0.12.X1 \n    + {[Ddp]@cell_%d_%d < 40.0 && [Stimulated]@cell_%d_%d <= 0.0} out( Ddp )@self:1.0.X2 \n \n  X2 -> {[Ignore]@cell_%d_%d => 1.0} in( Signal )@self:10000000.0.X2 \n    + {[Ddp]@cell_%d_%d < 60.0} out( Ddp )@self:1.0.[Ddp] | X2	\n    + {[Ddp]@cell_%d_%d => 60.0} in( Ddp | Excited | Ignore )@self:1.0.[Ddp] | X \nend \n \n", 
								i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j);
					} else if(i == (rows - 1)) {
						fprintf(filebk, 
								"let CellAgent_%d_%d be \n  X -> in( Signal )@self:1.0.[Stimulated] | [Ignore] | X1 \n \n  X1 -> {[Ignore]@cell_%d_%d => 1.0} in( Signal )@self:100000.0.X1	\n    + {[Ddp]@cell_%d_%d < 160.0 && [Stimulated]@cell_%d_%d => 1.0} read( Ddp )@self:0.12.[Ddp] | X1 \n    + {[Ddp]@cell_%d_%d => 160.0 && [Stimulated]@cell_%d_%d => 1.0} in( Stimulated )@self:1.0.[Excited] | [Signal]@next_1 | [Signal]@next_2 | [Signal]@next_3 | [Signal]@next_7 | [Signal]@next_8 | X1 \n    + {[Ddp]@cell_%d_%d => 40.0 && [Stimulated]@cell_%d_%d <= 0.0 && [Excited]@cell_%d_%d => 1.0} in( Ddp )@self:0.12.X1 \n    + {[Ddp]@cell_%d_%d < 40.0 && [Stimulated]@cell_%d_%d <= 0.0} out( Ddp )@self:1.0.X2 \n	\n  X2 -> {[Ignore]@cell_%d_%d => 1.0} in( Signal )@self:10000000.0.X2 \n    + {[Ddp]@cell_%d_%d < 60.0} out( Ddp )@self:1.0.[Ddp] | X2 \n    + {[Ddp]@cell_%d_%d => 60.0} in( Ddp | Excited | Ignore )@self:1.0.[Ddp] | X \nend \n \n", 
								i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j);
					} else if(j == 0) {
						fprintf(filebk, 
								"let CellAgent_%d_%d be \n  X -> in( Signal )@self:1.0.[Stimulated] | [Ignore] | X1 \n \n  X1 -> {[Ignore]@cell_%d_%d => 1.0} in( Signal )@self:100000.0.X1 \n    + {[Ddp]@cell_%d_%d < 160.0 && [Stimulated]@cell_%d_%d => 1.0} read( Ddp )@self:0.12.[Ddp] | X1 \n    + {[Ddp]@cell_%d_%d => 160.0 && [Stimulated]@cell_%d_%d => 1.0} in( Stimulated )@self:1.0.[Excited] | [Signal]@next_1 | [Signal]@next_2 | [Signal]@next_3 | [Signal]@next_4 | [Signal]@next_5 | X1 \n    + {[Ddp]@cell_%d_%d => 40.0 && [Stimulated]@cell_%d_%d <= 0.0 && [Excited]@cell_%d_%d => 1.0} in( Ddp )@self:0.12.X1 \n    + {[Ddp]@cell_%d_%d < 40.0 && [Stimulated]@cell_%d_%d <= 0.0} out( Ddp )@self:1.0.X2 \n \n  X2 -> {[Ignore]@cell_%d_%d => 1.0} in( Signal )@self:10000000.0.X2 \n    + {[Ddp]@cell_%d_%d < 60.0} out( Ddp )@self:1.0.[Ddp] | X2 \n    + {[Ddp]@cell_%d_%d => 60.0} in( Ddp | Excited | Ignore )@self:1.0.[Ddp] | X \nend \n \n", 
								i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j);
					} else if(j == (columns - 1)) {
						fprintf(filebk, 
								"let CellAgent_%d_%d be \n  X -> in( Signal )@self:1.0.[Stimulated] | [Ignore] | X1 \n \n  X1 -> {[Ignore]@cell_%d_%d => 1.0} in( Signal )@self:100000.0.X1 \n    + {[Ddp]@cell_%d_%d < 160.0 && [Stimulated]@cell_%d_%d => 1.0} read( Ddp )@self:0.12.[Ddp] | X1 \n    + {[Ddp]@cell_%d_%d => 160.0 && [Stimulated]@cell_%d_%d => 1.0} in( Stimulated )@self:1.0.[Excited] | [Signal]@next_1 | [Signal]@next_5 | [Signal]@next_6 | [Signal]@next_7 | [Signal]@next_8 | X1 \n    + {[Ddp]@cell_%d_%d => 40.0 && [Stimulated]@cell_%d_%d <= 0.0 && [Excited]@cell_%d_%d => 1.0} in( Ddp )@self:0.12.X1 \n    + {[Ddp]@cell_%d_%d < 40.0 && [Stimulated]@cell_%d_%d <= 0.0} out( Ddp )@self:1.0.X2 \n \n  X2 -> {[Ignore]@cell_%d_%d => 1.0} in( Signal )@self:10000000.0.X2 \n    + {[Ddp]@cell_%d_%d < 60.0} out( Ddp )@self:1.0.[Ddp] | X2 \n    + {[Ddp]@cell_%d_%d => 60.0} in( Ddp | Excited | Ignore )@self:1.0.[Ddp] | X \nend \n \n", 
								i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j);
					} else {
						fprintf(filebk, 
								"let CellAgent_%d_%d be \n  X -> in( Signal )@self:1.0.[Stimulated] | [Ignore] | X1 \n \n  X1 -> {[Ignore]@cell_%d_%d => 1.0} in( Signal )@self:100000.0.X1 \n    + {[Ddp]@cell_%d_%d < 160.0 && [Stimulated]@cell_%d_%d => 1.0} read( Ddp )@self:0.12.[Ddp] | X1 \n    + {[Ddp]@cell_%d_%d => 160.0 && [Stimulated]@cell_%d_%d => 1.0} in( Stimulated )@self:1.0.[Excited] | [Signal]@next_1 | [Signal]@next_2 | [Signal]@next_3 | [Signal]@next_4 | [Signal]@next_5 | [Signal]@next_6 | [Signal]@next_7 | [Signal]@next_8 | X1 \n    + {[Ddp]@cell_%d_%d => 40.0 && [Stimulated]@cell_%d_%d <= 0.0 && [Excited]@cell_%d_%d => 1.0} in( Ddp )@self:0.12.X1 \n    + {[Ddp]@cell_%d_%d < 40.0 && [Stimulated]@cell_%d_%d <= 0.0} out( Ddp )@self:1.0.X2 \n \n  X2 -> {[Ignore]@cell_%d_%d => 1.0} in( Signal )@self:10000000.0.X2 \n    + {[Ddp]@cell_%d_%d < 60.0} out( Ddp )@self:1.0.[Ddp] | X2 \n    + {[Ddp]@cell_%d_%d => 60.0} in( Ddp | Excited | Ignore )@self:1.0.[Ddp] | X \nend \n \n", 
								i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j);
					}
				}
			}
			
			fprintf(filebk, "\nsystem:\n");
			
			for (i = 0; i < rows; ++i) {
				for (j = 0; j < columns; ++j) {
					if (i == (rows - 1) &&  j == (columns - 1)) {
						fprintf(filebk, "\tcell_%d_%d::[Ddp]{60} || cell_%d_%d::CellAgent_%d_%d[X]{1} \n", i, j, i, j, i, j);
						continue;
					}
					fprintf(filebk, "\tcell_%d_%d::[Ddp]{60} || cell_%d_%d::CellAgent_%d_%d[X]{1} || \n", i, j, i, j, i, j);
				}
			}
			
			for (i = starting_row; i <= ending_row; ++i) {
				for (int j = starting_column; j <= ending_column; ++j) {
					fprintf(filebk, "\t|| cell_%d_%d::[Signal]{1}\n", i, j);
				}
			}
			fprintf(filebk, "end");
		} 
		else if (mode == LIST_MODE) {
			//Crea una lista di cellule
			fprintf(filebk, "bio\n\nlocalities:\nlogical self;\nlogical next;\n");
			for (i = 0; i < rows; ++i) {
				for (j = 0; j < columns; ++j) {
					fprintf(filebk, "physical cell_%d_%d;\n", i, j);
				}
			}
			fprintf(filebk, "\nenvironments:\n");
			
			for (i = 0; i < rows; ++i) {
				for (j = 0; j < columns; ++j) {
					if (i == (rows - 1)) {
						fprintf(filebk, "cell_%d_%d: [self -> cell_%d_%d];\n", i, j, i, j);
						continue;
					}
					fprintf(filebk, "cell_%d_%d: [self -> cell_%d_%d, next -> cell_%d_%d];\n", i, j, i, j, i+1, j);
				}
			}
			
			fprintf(filebk, "\nmessages: Ddp, Signal, Stimulated, Excited, Ignore;\n\nagents:\n");
			
			for (i = 0; i < rows; ++i) {
				for (j = 0; j < columns; ++j) {
					if (i == (rows - 1)) {
						fprintf(filebk, 
								"let CellAgent_%d_%d be \n  X -> in( Signal )@self:1.0.[Stimulated] | [Ignore] | X1 \n \n  X1 -> {[Ignore]@cell_%d_%d => 1.0} in( Signal )@self:100000.0.X1 \n    + {[Ddp]@cell_%d_%d < 160.0 && [Stimulated]@cell_%d_%d => 1.0} read( Ddp )@self:0.12.[Ddp] | X1 \n    + {[Ddp]@cell_%d_%d => 160.0 && [Stimulated]@cell_%d_%d => 1.0} in( Stimulated )@self:1.0.[Excited] | X1 \n    + {[Ddp]@cell_%d_%d => 40.0 && [Stimulated]@cell_%d_%d <= 0.0 && [Excited]@cell_%d_%d => 1.0} in( Ddp )@self:0.12.X1 \n    + {[Ddp]@cell_%d_%d < 40.0 && [Stimulated]@cell_%d_%d <= 0.0} out( Ddp )@self:1.0.X2 \n	\n  X2 -> {[Ignore]@cell_%d_%d => 1.0} in( Signal )@self:10000000.0.X2 \n    + {[Ddp]@cell_%d_%d < 60.0} out( Ddp )@self:1.0.[Ddp] | X2 \n    + {[Ddp]@cell_%d_%d => 60.0} in( Ddp | Excited | Ignore )@self:1.0.[Ddp] | X \nend \n \n", 
								i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j);
						continue;
					}
					fprintf(filebk, 
							"let CellAgent_%d_%d be \n  X -> in( Signal )@self:1.0.[Stimulated] | [Ignore] | X1 \n \n  X1 -> {[Ignore]@cell_%d_%d => 1.0} in( Signal )@self:100000.0.X1 \n    + {[Ddp]@cell_%d_%d < 160.0 && [Stimulated]@cell_%d_%d => 1.0} read( Ddp )@self:0.12.[Ddp] | X1 \n    + {[Ddp]@cell_%d_%d => 160.0 && [Stimulated]@cell_%d_%d => 1.0} in( Stimulated )@self:1.0.[Excited] | [Signal]@next | X1 \n    + {[Ddp]@cell_%d_%d => 40.0 && [Stimulated]@cell_%d_%d <= 0.0 && [Excited]@cell_%d_%d => 1.0} in( Ddp )@self:0.12.X1 \n    + {[Ddp]@cell_%d_%d < 40.0 && [Stimulated]@cell_%d_%d <= 0.0} out( Ddp )@self:1.0.X2 \n	\n  X2 -> {[Ignore]@cell_%d_%d => 1.0} in( Signal )@self:10000000.0.X2 \n    + {[Ddp]@cell_%d_%d < 60.0} out( Ddp )@self:1.0.[Ddp] | X2 \n    + {[Ddp]@cell_%d_%d => 60.0} in( Ddp | Excited | Ignore )@self:1.0.[Ddp] | X \nend \n \n", 
							i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j);
				}
			}
			
			fprintf(filebk, "\nsystem:\n");
			
			for (i = 0; i < rows; ++i) {
				for (j = 0; j < columns; ++j) {
					if ((i == (rows - 1)) && (j == (columns - 1))) {
						fprintf(filebk, "\tcell_%d_%d::[Ddp]{60} || cell_%d_%d::CellAgent_%d_%d[X]{1} \n", i, j, i, j, i, j);
						continue;
					}
					
					fprintf(filebk, "\tcell_%d_%d::[Ddp]{60} || cell_%d_%d::CellAgent_%d_%d[X]{1} || \n", i, j, i, j, i, j);				
				}
			}
			
			for (i = starting_row; i <= ending_row; ++i) {
				for (j = 0; j < columns; ++j) {
					fprintf(filebk, "\t|| cell_%d_%d::[Signal]{1}\n", i, j);
				}
			}
			fprintf(filebk, "end");
		}
	}
	else /*Ion Mode*/{
		if(mode == SQUARE_MODE ) { //Square Mode
			fprintf(filebk, "bio\n\nlocalities:\nlogical self;\nlogical next_1;\nlogical next_2;\nlogical next_3;\nlogical next_4;\nlogical next_5;\nlogical next_6;\nlogical next_7;\nlogical next_8;\n");
			
			for (i = 0; i < rows; ++i) {
				for (j = 0; j < columns; ++j) {
					fprintf(filebk, "physical inside_%d_%d;\n", i, j);
					fprintf(filebk, "physical outside_%d_%d;\n", i, j);
				}
			}
			fprintf(filebk, "\nenvironments:\n");
			
			char* n1 = malloc(sizeof(char) * MAX_CHAR_PER_ROW);
			char* n2 = malloc(sizeof(char) * MAX_CHAR_PER_ROW);
			char* n3 = malloc(sizeof(char) * MAX_CHAR_PER_ROW);
			char* n4 = malloc(sizeof(char) * MAX_CHAR_PER_ROW);
			char* n5 = malloc(sizeof(char) * MAX_CHAR_PER_ROW);
			char* n6 = malloc(sizeof(char) * MAX_CHAR_PER_ROW);
			char* n7 = malloc(sizeof(char) * MAX_CHAR_PER_ROW);
			char* n8 = malloc(sizeof(char) * MAX_CHAR_PER_ROW);
			
			for (i = 0; i < rows; ++i) {
				for (j = 0; j < columns; ++j) {
					sprintf(n1, "next_1 -> inside_%d_%d", (i-1), j);
					sprintf(n2, "next_2 -> inside_%d_%d", (i-1), (j+1));
					sprintf(n3, "next_3 -> inside_%d_%d", i, (j+1));
					sprintf(n4, "next_4 -> inside_%d_%d", (i+1), (j+1));
					sprintf(n5, "next_5 -> inside_%d_%d", (i+1), j);
					sprintf(n6, "next_6 -> inside_%d_%d", (i+1), (j-1));
					sprintf(n7, "next_7 -> inside_%d_%d", i, (j-1));
					sprintf(n8, "next_8 -> inside_%d_%d", (i-1), (j-1));
					
					
					if(i == 0 && j == 0) {
						fprintf(filebk, "inside_%d_%d: [self -> inside_%d_%d, %s, %s, %s];\n", i, j, i, j, n3, n4, n5);
					} else if(i == 0 && j == (columns - 1)) {
						fprintf(filebk, "inside_%d_%d: [self -> inside_%d_%d, %s, %s, %s];\n", i, j, i, j, n5, n6, n7);
					} else if(i == 0) {
						fprintf(filebk, "inside_%d_%d: [self -> inside_%d_%d, %s, %s, %s, %s, %s];\n", i, j, i, j, n3, n4, n5, n6, n7);
					} else if(i == (rows - 1) && j == 0) {
						fprintf(filebk, "inside_%d_%d: [self -> inside_%d_%d, %s, %s, %s];\n", i, j, i, j, n1, n2, n3);
					} else if(i == (rows - 1) && j == (columns - 1)) {
						fprintf(filebk, "inside_%d_%d: [self -> inside_%d_%d, %s, %s, %s];\n", i, j, i, j, n1, n7, n8);
					} else if(i == (rows - 1)) {
						fprintf(filebk, "inside_%d_%d: [self -> inside_%d_%d, %s, %s, %s, %s, %s];\n", i, j, i, j, n1, n2, n3, n7, n8);
					} else if(j == 0) {
						fprintf(filebk, "inside_%d_%d: [self -> inside_%d_%d, %s, %s, %s, %s, %s];\n", i, j, i, j, n1, n2, n3, n4, n5);
					} else if(j == (columns - 1)) {
						fprintf(filebk, "inside_%d_%d: [self -> inside_%d_%d, %s, %s, %s, %s, %s];\n", i, j, i, j, n1, n5, n6, n7, n8);
					} else {
						fprintf(filebk, "inside_%d_%d: [self -> inside_%d_%d, %s, %s, %s, %s, %s, %s, %s, %s];\n", i, j, i, j, n1, n2, n3, n4, n5, n6, n7, n8);
					}
				}
			}
			
			free(n1);
			free(n2);
			free(n3);
			free(n4);
			free(n5);
			free(n6);
			free(n7);
			free(n8);
			
			n1 = NULL;
			n2 = NULL;
			n3 = NULL;
			n4 = NULL;
			n5 = NULL;
			n6 = NULL;
			n7 = NULL;
			n8 = NULL;
			
			fprintf(filebk, "\nmessages: Na, K, Signal, NaChan, KChan, Pump, Ddp, Ready, Ignore;\n\nagents:\n");
			
			for (i = 0; i < rows; ++i) {
				for (j = 0; j < columns; ++j) {
					if(i == 0 && j == 0) {
						fprintf(filebk, 
								"let CellAgent_%d_%d be \nX ->  in( Signal )@self:1.0.[NaChan] | [Ignore] | X1 \n \nX1  ->  {[Ignore]@inside_%d_%d => 1.0} in( Signal )@self:1000000000000000.0.X1 \n+   {[NaChan]@inside_%d_%d > 0.0 && (8.314*310.15*ln([Na]@outside_%d_%d / [Na]@inside_%d_%d)) > -(96.485*30)} in( Na )@outside_%d_%d:0.65.[Na] | X1 \n+   {[NaChan]@inside_%d_%d > 0.0 && (8.314*310.15*ln([Na]@outside_%d_%d / [Na]@inside_%d_%d)) <= -(96.485*30)} in( NaChan )@self:10.0.[KChan] | [Signal]@next_3 | [Signal]@next_4 | [Signal]@next_5 | X1 \n+   {[KChan]@inside_%d_%d > 0.0 && (8.314*310.15*ln([K]@outside_%d_%d / [K]@inside_%d_%d)) < (96.485*90)} in( K )@self:10.0.[K]@outside_%d_%d | X1 \n+   {[KChan]@inside_%d_%d > 0.0 && (8.314*310.15*ln([K]@outside_%d_%d / [K]@inside_%d_%d)) => (96.485*90)} in( KChan )@self:0.7.[Pump] | X3 \n \nX3  ->  eval(CellAgent_%d_%d[X4])@self:100000.0.X2 \n \nX4  ->  {[Ignore]@inside_%d_%d => 1.0} in( Signal )@self:1000000000000000.0.X1 \n+   {[Pump]@inside_%d_%d > 0.0 && [Ddp]@inside_%d_%d < 15.0} out( Ddp )@self:100000.0.X4 \n+   {[Pump]@inside_%d_%d <= 0.0} in( Ddp )@self:1.0.X4 \n+   {[Pump]@inside_%d_%d > 0.0 && [Ready]@inside_%d_%d <= 0.0 && [Ddp]@inside_%d_%d => 15.0} out( Ready )@self:10000.0.X4 \n \nX2  ->  {[Ignore]@inside_%d_%d => 1.0} in( Signal )@self:1000000000000000.0.X1 \n+   {[Pump]@inside_%d_%d > 0.0 && [K]@inside_%d_%d < 117.0} in( K )@outside_%d_%d:10000.0.[K]@self | X2 \n+   {[Pump]@inside_%d_%d > 0.0 && [Na]@outside_%d_%d < 63.0} in( Na )@self:10000.0.[Na]@outside_%d_%d | X2 \n+   {[Pump]@inside_%d_%d > 0.0 && [K]@inside_%d_%d => 117.0 && [Na]@outside_%d_%d => 63.0} in( Ignore | Pump | Ready )@self:10000.0.X \n end \n \n", 
								i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j);
					} else if(i == 0 && j == (columns - 1)) {
						fprintf(filebk, 
								"let CellAgent_%d_%d be \nX ->  in( Signal )@self:1.0.[NaChan] | [Ignore] | X1 \n \nX1  ->  {[Ignore]@inside_%d_%d => 1.0} in( Signal )@self:1000000000000000.0.X1 \n+   {[NaChan]@inside_%d_%d > 0.0 && (8.314*310.15*ln([Na]@outside_%d_%d / [Na]@inside_%d_%d)) > -(96.485*30)} in( Na )@outside_%d_%d:0.65.[Na] | X1 \n+   {[NaChan]@inside_%d_%d > 0.0 && (8.314*310.15*ln([Na]@outside_%d_%d / [Na]@inside_%d_%d)) <= -(96.485*30)} in( NaChan )@self:10.0.[KChan] | [Signal]@next_5 | [Signal]@next_6 | [Signal]@next_7 | X1 \n+   {[KChan]@inside_%d_%d > 0.0 && (8.314*310.15*ln([K]@outside_%d_%d / [K]@inside_%d_%d)) < (96.485*90)} in( K )@self:10.0.[K]@outside_%d_%d | X1 \n+   {[KChan]@inside_%d_%d > 0.0 && (8.314*310.15*ln([K]@outside_%d_%d / [K]@inside_%d_%d)) => (96.485*90)} in( KChan )@self:0.7.[Pump] | X3 \n \nX3  ->  eval(CellAgent_%d_%d[X4])@self:100000.0.X2 \n \nX4  ->  {[Ignore]@inside_%d_%d => 1.0} in( Signal )@self:1000000000000000.0.X1 \n+   {[Pump]@inside_%d_%d > 0.0 && [Ddp]@inside_%d_%d < 15.0} out( Ddp )@self:100000.0.X4 \n+   {[Pump]@inside_%d_%d <= 0.0} in( Ddp )@self:1.0.X4 \n+   {[Pump]@inside_%d_%d > 0.0 && [Ready]@inside_%d_%d <= 0.0 && [Ddp]@inside_%d_%d => 15.0} out( Ready )@self:10000.0.X4 \n \nX2  ->  {[Ignore]@inside_%d_%d => 1.0} in( Signal )@self:1000000000000000.0.X1 \n+   {[Pump]@inside_%d_%d > 0.0 && [K]@inside_%d_%d < 117.0} in( K )@outside_%d_%d:10000.0.[K]@self | X2 \n+   {[Pump]@inside_%d_%d > 0.0 && [Na]@outside_%d_%d < 63.0} in( Na )@self:10000.0.[Na]@outside_%d_%d | X2 \n+   {[Pump]@inside_%d_%d > 0.0 && [K]@inside_%d_%d => 117.0 && [Na]@outside_%d_%d => 63.0} in( Ignore | Pump | Ready )@self:10000.0.X \n end \n \n", 
								i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j);
					} else if(i == 0) {
						fprintf(filebk, 
								"let CellAgent_%d_%d be \nX ->  in( Signal )@self:1.0.[NaChan] | [Ignore] | X1 \n \nX1  ->  {[Ignore]@inside_%d_%d => 1.0} in( Signal )@self:1000000000000000.0.X1 \n+   {[NaChan]@inside_%d_%d > 0.0 && (8.314*310.15*ln([Na]@outside_%d_%d / [Na]@inside_%d_%d)) > -(96.485*30)} in( Na )@outside_%d_%d:0.65.[Na] | X1 \n+   {[NaChan]@inside_%d_%d > 0.0 && (8.314*310.15*ln([Na]@outside_%d_%d / [Na]@inside_%d_%d)) <= -(96.485*30)} in( NaChan )@self:10.0.[KChan] | [Signal]@next_3 | [Signal]@next_4 | [Signal]@next_5 | [Signal]@next_6 | [Signal]@next_7 | X1 \n+   {[KChan]@inside_%d_%d > 0.0 && (8.314*310.15*ln([K]@outside_%d_%d / [K]@inside_%d_%d)) < (96.485*90)} in( K )@self:10.0.[K]@outside_%d_%d | X1 \n+   {[KChan]@inside_%d_%d > 0.0 && (8.314*310.15*ln([K]@outside_%d_%d / [K]@inside_%d_%d)) => (96.485*90)} in( KChan )@self:0.7.[Pump] | X3 \n \nX3  ->  eval(CellAgent_%d_%d[X4])@self:100000.0.X2 \n \nX4  ->  {[Ignore]@inside_%d_%d => 1.0} in( Signal )@self:1000000000000000.0.X1 \n+   {[Pump]@inside_%d_%d > 0.0 && [Ddp]@inside_%d_%d < 15.0} out( Ddp )@self:100000.0.X4 \n+   {[Pump]@inside_%d_%d <= 0.0} in( Ddp )@self:1.0.X4 \n+   {[Pump]@inside_%d_%d > 0.0 && [Ready]@inside_%d_%d <= 0.0 && [Ddp]@inside_%d_%d => 15.0} out( Ready )@self:10000.0.X4 \n \nX2  ->  {[Ignore]@inside_%d_%d => 1.0} in( Signal )@self:1000000000000000.0.X1 \n+   {[Pump]@inside_%d_%d > 0.0 && [K]@inside_%d_%d < 117.0} in( K )@outside_%d_%d:10000.0.[K]@self | X2 \n+   {[Pump]@inside_%d_%d > 0.0 && [Na]@outside_%d_%d < 63.0} in( Na )@self:10000.0.[Na]@outside_%d_%d | X2 \n+   {[Pump]@inside_%d_%d > 0.0 && [K]@inside_%d_%d => 117.0 && [Na]@outside_%d_%d => 63.0} in( Ignore | Pump | Ready )@self:10000.0.X \n end \n \n", 
								i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j);
					} else if(i == (rows - 1) && j == 0) {
						fprintf(filebk, 
								"let CellAgent_%d_%d be \nX ->  in( Signal )@self:1.0.[NaChan] | [Ignore] | X1 \n \nX1  ->  {[Ignore]@inside_%d_%d => 1.0} in( Signal )@self:1000000000000000.0.X1 \n+   {[NaChan]@inside_%d_%d > 0.0 && (8.314*310.15*ln([Na]@outside_%d_%d / [Na]@inside_%d_%d)) > -(96.485*30)} in( Na )@outside_%d_%d:0.65.[Na] | X1 \n+   {[NaChan]@inside_%d_%d > 0.0 && (8.314*310.15*ln([Na]@outside_%d_%d / [Na]@inside_%d_%d)) <= -(96.485*30)} in( NaChan )@self:10.0.[KChan] | [Signal]@next_1 | [Signal]@next_2 | [Signal]@next_3 | X1 \n+   {[KChan]@inside_%d_%d > 0.0 && (8.314*310.15*ln([K]@outside_%d_%d / [K]@inside_%d_%d)) < (96.485*90)} in( K )@self:10.0.[K]@outside_%d_%d | X1 \n+   {[KChan]@inside_%d_%d > 0.0 && (8.314*310.15*ln([K]@outside_%d_%d / [K]@inside_%d_%d)) => (96.485*90)} in( KChan )@self:0.7.[Pump] | X3 \n \nX3  ->  eval(CellAgent_%d_%d[X4])@self:100000.0.X2 \n \nX4  ->  {[Ignore]@inside_%d_%d => 1.0} in( Signal )@self:1000000000000000.0.X1 \n+   {[Pump]@inside_%d_%d > 0.0 && [Ddp]@inside_%d_%d < 15.0} out( Ddp )@self:100000.0.X4 \n+   {[Pump]@inside_%d_%d <= 0.0} in( Ddp )@self:1.0.X4 \n+   {[Pump]@inside_%d_%d > 0.0 && [Ready]@inside_%d_%d <= 0.0 && [Ddp]@inside_%d_%d => 15.0} out( Ready )@self:10000.0.X4 \n \nX2  ->  {[Ignore]@inside_%d_%d => 1.0} in( Signal )@self:1000000000000000.0.X1 \n+   {[Pump]@inside_%d_%d > 0.0 && [K]@inside_%d_%d < 117.0} in( K )@outside_%d_%d:10000.0.[K]@self | X2 \n+   {[Pump]@inside_%d_%d > 0.0 && [Na]@outside_%d_%d < 63.0} in( Na )@self:10000.0.[Na]@outside_%d_%d | X2 \n+   {[Pump]@inside_%d_%d > 0.0 && [K]@inside_%d_%d => 117.0 && [Na]@outside_%d_%d => 63.0} in( Ignore | Pump | Ready )@self:10000.0.X \n end \n \n", 
								i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j);
					} else if(i == (rows - 1) && j == (columns - 1)) {
						fprintf(filebk, 
								"let CellAgent_%d_%d be \nX ->  in( Signal )@self:1.0.[NaChan] | [Ignore] | X1 \n \nX1  ->  {[Ignore]@inside_%d_%d => 1.0} in( Signal )@self:1000000000000000.0.X1 \n+   {[NaChan]@inside_%d_%d > 0.0 && (8.314*310.15*ln([Na]@outside_%d_%d / [Na]@inside_%d_%d)) > -(96.485*30)} in( Na )@outside_%d_%d:0.65.[Na] | X1 \n+   {[NaChan]@inside_%d_%d > 0.0 && (8.314*310.15*ln([Na]@outside_%d_%d / [Na]@inside_%d_%d)) <= -(96.485*30)} in( NaChan )@self:10.0.[KChan] | [Signal]@next_1 | [Signal]@next_7 | [Signal]@next_8 | X1 \n+   {[KChan]@inside_%d_%d > 0.0 && (8.314*310.15*ln([K]@outside_%d_%d / [K]@inside_%d_%d)) < (96.485*90)} in( K )@self:10.0.[K]@outside_%d_%d | X1 \n+   {[KChan]@inside_%d_%d > 0.0 && (8.314*310.15*ln([K]@outside_%d_%d / [K]@inside_%d_%d)) => (96.485*90)} in( KChan )@self:0.7.[Pump] | X3 \n \nX3  ->  eval(CellAgent_%d_%d[X4])@self:100000.0.X2 \n \nX4  ->  {[Ignore]@inside_%d_%d => 1.0} in( Signal )@self:1000000000000000.0.X1 \n+   {[Pump]@inside_%d_%d > 0.0 && [Ddp]@inside_%d_%d < 15.0} out( Ddp )@self:100000.0.X4 \n+   {[Pump]@inside_%d_%d <= 0.0} in( Ddp )@self:1.0.X4 \n+   {[Pump]@inside_%d_%d > 0.0 && [Ready]@inside_%d_%d <= 0.0 && [Ddp]@inside_%d_%d => 15.0} out( Ready )@self:10000.0.X4 \n \nX2  ->  {[Ignore]@inside_%d_%d => 1.0} in( Signal )@self:1000000000000000.0.X1 \n+   {[Pump]@inside_%d_%d > 0.0 && [K]@inside_%d_%d < 117.0} in( K )@outside_%d_%d:10000.0.[K]@self | X2 \n+   {[Pump]@inside_%d_%d > 0.0 && [Na]@outside_%d_%d < 63.0} in( Na )@self:10000.0.[Na]@outside_%d_%d | X2 \n+   {[Pump]@inside_%d_%d > 0.0 && [K]@inside_%d_%d => 117.0 && [Na]@outside_%d_%d => 63.0} in( Ignore | Pump | Ready )@self:10000.0.X \n end \n \n", 
								i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j);
					} else if(i == (rows - 1)) {
						fprintf(filebk, 
								"let CellAgent_%d_%d be \nX ->  in( Signal )@self:1.0.[NaChan] | [Ignore] | X1 \n \nX1  ->  {[Ignore]@inside_%d_%d => 1.0} in( Signal )@self:1000000000000000.0.X1 \n+   {[NaChan]@inside_%d_%d > 0.0 && (8.314*310.15*ln([Na]@outside_%d_%d / [Na]@inside_%d_%d)) > -(96.485*30)} in( Na )@outside_%d_%d:0.65.[Na] | X1 \n+   {[NaChan]@inside_%d_%d > 0.0 && (8.314*310.15*ln([Na]@outside_%d_%d / [Na]@inside_%d_%d)) <= -(96.485*30)} in( NaChan )@self:10.0.[KChan] | [Signal]@next_1 | [Signal]@next_2 | [Signal]@next_3 | [Signal]@next_7 | [Signal]@next_8 | X1 \n+   {[KChan]@inside_%d_%d > 0.0 && (8.314*310.15*ln([K]@outside_%d_%d / [K]@inside_%d_%d)) < (96.485*90)} in( K )@self:10.0.[K]@outside_%d_%d | X1 \n+   {[KChan]@inside_%d_%d > 0.0 && (8.314*310.15*ln([K]@outside_%d_%d / [K]@inside_%d_%d)) => (96.485*90)} in( KChan )@self:0.7.[Pump] | X3 \n \nX3  ->  eval(CellAgent_%d_%d[X4])@self:100000.0.X2 \n \nX4  ->  {[Ignore]@inside_%d_%d => 1.0} in( Signal )@self:1000000000000000.0.X1 \n+   {[Pump]@inside_%d_%d > 0.0 && [Ddp]@inside_%d_%d < 15.0} out( Ddp )@self:100000.0.X4 \n+   {[Pump]@inside_%d_%d <= 0.0} in( Ddp )@self:1.0.X4 \n+   {[Pump]@inside_%d_%d > 0.0 && [Ready]@inside_%d_%d <= 0.0 && [Ddp]@inside_%d_%d => 15.0} out( Ready )@self:10000.0.X4 \n \nX2  ->  {[Ignore]@inside_%d_%d => 1.0} in( Signal )@self:1000000000000000.0.X1 \n+   {[Pump]@inside_%d_%d > 0.0 && [K]@inside_%d_%d < 117.0} in( K )@outside_%d_%d:10000.0.[K]@self | X2 \n+   {[Pump]@inside_%d_%d > 0.0 && [Na]@outside_%d_%d < 63.0} in( Na )@self:10000.0.[Na]@outside_%d_%d | X2 \n+   {[Pump]@inside_%d_%d > 0.0 && [K]@inside_%d_%d => 117.0 && [Na]@outside_%d_%d => 63.0} in( Ignore | Pump | Ready )@self:10000.0.X \n end \n \n", 
								i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j);
					} else if(j == 0) {
						fprintf(filebk, 
								"let CellAgent_%d_%d be \nX ->  in( Signal )@self:1.0.[NaChan] | [Ignore] | X1 \n \nX1  ->  {[Ignore]@inside_%d_%d => 1.0} in( Signal )@self:1000000000000000.0.X1 \n+   {[NaChan]@inside_%d_%d > 0.0 && (8.314*310.15*ln([Na]@outside_%d_%d / [Na]@inside_%d_%d)) > -(96.485*30)} in( Na )@outside_%d_%d:0.65.[Na] | X1 \n+   {[NaChan]@inside_%d_%d > 0.0 && (8.314*310.15*ln([Na]@outside_%d_%d / [Na]@inside_%d_%d)) <= -(96.485*30)} in( NaChan )@self:10.0.[KChan] | [Signal]@next_1 | [Signal]@next_2 | [Signal]@next_3 | [Signal]@next_4 | [Signal]@next_5 | X1 \n+   {[KChan]@inside_%d_%d > 0.0 && (8.314*310.15*ln([K]@outside_%d_%d / [K]@inside_%d_%d)) < (96.485*90)} in( K )@self:10.0.[K]@outside_%d_%d | X1 \n+   {[KChan]@inside_%d_%d > 0.0 && (8.314*310.15*ln([K]@outside_%d_%d / [K]@inside_%d_%d)) => (96.485*90)} in( KChan )@self:0.7.[Pump] | X3 \n \nX3  ->  eval(CellAgent_%d_%d[X4])@self:100000.0.X2 \n \nX4  ->  {[Ignore]@inside_%d_%d => 1.0} in( Signal )@self:1000000000000000.0.X1 \n+   {[Pump]@inside_%d_%d > 0.0 && [Ddp]@inside_%d_%d < 15.0} out( Ddp )@self:100000.0.X4 \n+   {[Pump]@inside_%d_%d <= 0.0} in( Ddp )@self:1.0.X4 \n+   {[Pump]@inside_%d_%d > 0.0 && [Ready]@inside_%d_%d <= 0.0 && [Ddp]@inside_%d_%d => 15.0} out( Ready )@self:10000.0.X4 \n \nX2  ->  {[Ignore]@inside_%d_%d => 1.0} in( Signal )@self:1000000000000000.0.X1 \n+   {[Pump]@inside_%d_%d > 0.0 && [K]@inside_%d_%d < 117.0} in( K )@outside_%d_%d:10000.0.[K]@self | X2 \n+   {[Pump]@inside_%d_%d > 0.0 && [Na]@outside_%d_%d < 63.0} in( Na )@self:10000.0.[Na]@outside_%d_%d | X2 \n+   {[Pump]@inside_%d_%d > 0.0 && [K]@inside_%d_%d => 117.0 && [Na]@outside_%d_%d => 63.0} in( Ignore | Pump | Ready )@self:10000.0.X \n end \n \n", 
								i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j);
					} else if(j == (columns - 1)) {
						fprintf(filebk, 
								"let CellAgent_%d_%d be \nX ->  in( Signal )@self:1.0.[NaChan] | [Ignore] | X1 \n \nX1  ->  {[Ignore]@inside_%d_%d => 1.0} in( Signal )@self:1000000000000000.0.X1 \n+   {[NaChan]@inside_%d_%d > 0.0 && (8.314*310.15*ln([Na]@outside_%d_%d / [Na]@inside_%d_%d)) > -(96.485*30)} in( Na )@outside_%d_%d:0.65.[Na] | X1 \n+   {[NaChan]@inside_%d_%d > 0.0 && (8.314*310.15*ln([Na]@outside_%d_%d / [Na]@inside_%d_%d)) <= -(96.485*30)} in( NaChan )@self:10.0.[KChan] | [Signal]@next_1 | [Signal]@next_5 | [Signal]@next_6 | [Signal]@next_7 | [Signal]@next_8 | X1 \n+   {[KChan]@inside_%d_%d > 0.0 && (8.314*310.15*ln([K]@outside_%d_%d / [K]@inside_%d_%d)) < (96.485*90)} in( K )@self:10.0.[K]@outside_%d_%d | X1 \n+   {[KChan]@inside_%d_%d > 0.0 && (8.314*310.15*ln([K]@outside_%d_%d / [K]@inside_%d_%d)) => (96.485*90)} in( KChan )@self:0.7.[Pump] | X3 \n \nX3  ->  eval(CellAgent_%d_%d[X4])@self:100000.0.X2 \n \nX4  ->  {[Ignore]@inside_%d_%d => 1.0} in( Signal )@self:1000000000000000.0.X1 \n+   {[Pump]@inside_%d_%d > 0.0 && [Ddp]@inside_%d_%d < 15.0} out( Ddp )@self:100000.0.X4 \n+   {[Pump]@inside_%d_%d <= 0.0} in( Ddp )@self:1.0.X4 \n+   {[Pump]@inside_%d_%d > 0.0 && [Ready]@inside_%d_%d <= 0.0 && [Ddp]@inside_%d_%d => 15.0} out( Ready )@self:10000.0.X4 \n \nX2  ->  {[Ignore]@inside_%d_%d => 1.0} in( Signal )@self:1000000000000000.0.X1 \n+   {[Pump]@inside_%d_%d > 0.0 && [K]@inside_%d_%d < 117.0} in( K )@outside_%d_%d:10000.0.[K]@self | X2 \n+   {[Pump]@inside_%d_%d > 0.0 && [Na]@outside_%d_%d < 63.0} in( Na )@self:10000.0.[Na]@outside_%d_%d | X2 \n+   {[Pump]@inside_%d_%d > 0.0 && [K]@inside_%d_%d => 117.0 && [Na]@outside_%d_%d => 63.0} in( Ignore | Pump | Ready )@self:10000.0.X \n end \n \n", 
								i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j);
					} else {
						fprintf(filebk, 
								"let CellAgent_%d_%d be \nX ->  in( Signal )@self:1.0.[NaChan] | [Ignore] | X1 \n \nX1  ->  {[Ignore]@inside_%d_%d => 1.0} in( Signal )@self:1000000000000000.0.X1 \n+   {[NaChan]@inside_%d_%d > 0.0 && (8.314*310.15*ln([Na]@outside_%d_%d / [Na]@inside_%d_%d)) > -(96.485*30)} in( Na )@outside_%d_%d:0.65.[Na] | X1 \n+   {[NaChan]@inside_%d_%d > 0.0 && (8.314*310.15*ln([Na]@outside_%d_%d / [Na]@inside_%d_%d)) <= -(96.485*30)} in( NaChan )@self:10.0.[KChan] | [Signal]@next_1 | [Signal]@next_2 | [Signal]@next_3 | [Signal]@next_4 | [Signal]@next_5 | [Signal]@next_6 | [Signal]@next_7 | [Signal]@next_8 | X1 \n+   {[KChan]@inside_%d_%d > 0.0 && (8.314*310.15*ln([K]@outside_%d_%d / [K]@inside_%d_%d)) < (96.485*90)} in( K )@self:10.0.[K]@outside_%d_%d | X1 \n+   {[KChan]@inside_%d_%d > 0.0 && (8.314*310.15*ln([K]@outside_%d_%d / [K]@inside_%d_%d)) => (96.485*90)} in( KChan )@self:0.7.[Pump] | X3 \n \nX3  ->  eval(CellAgent_%d_%d[X4])@self:100000.0.X2 \n \nX4  ->  {[Ignore]@inside_%d_%d => 1.0} in( Signal )@self:1000000000000000.0.X1 \n+   {[Pump]@inside_%d_%d > 0.0 && [Ddp]@inside_%d_%d < 15.0} out( Ddp )@self:100000.0.X4 \n+   {[Pump]@inside_%d_%d <= 0.0} in( Ddp )@self:1.0.X4 \n+   {[Pump]@inside_%d_%d > 0.0 && [Ready]@inside_%d_%d <= 0.0 && [Ddp]@inside_%d_%d => 15.0} out( Ready )@self:10000.0.X4 \n \nX2  ->  {[Ignore]@inside_%d_%d => 1.0} in( Signal )@self:1000000000000000.0.X1 \n+   {[Pump]@inside_%d_%d > 0.0 && [K]@inside_%d_%d < 117.0} in( K )@outside_%d_%d:10000.0.[K]@self | X2 \n+   {[Pump]@inside_%d_%d > 0.0 && [Na]@outside_%d_%d < 63.0} in( Na )@self:10000.0.[Na]@outside_%d_%d | X2 \n+   {[Pump]@inside_%d_%d > 0.0 && [K]@inside_%d_%d => 117.0 && [Na]@outside_%d_%d => 63.0} in( Ignore | Pump | Ready )@self:10000.0.X \n end \n \n", 
								i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j);
					}
				}
			}
			
			fprintf(filebk, "\nsystem:\n");
			
			for (i = 0; i < rows; ++i) {
				for (j = 0; j < columns; ++j) {
					if (i == (rows - 1) &&  j == (columns - 1)) {
						fprintf(filebk, "\tinside_%d_%d::CellAgent_%d_%d[X]{1} || inside_%d_%d::[K]{117} || outside_%d_%d::[K]{4} || inside_%d_%d::[Na]{20} || outside_%d_%d::[Na]{63} \n", i, j, i, j, i, j, i, j, i, j, i, j, i, j);
						continue;
					}
					fprintf(filebk, "\tinside_%d_%d::CellAgent_%d_%d[X]{1} || inside_%d_%d::[K]{117} || outside_%d_%d::[K]{4} || inside_%d_%d::[Na]{20} || outside_%d_%d::[Na]{63} || \n", i, j, i, j, i, j, i, j, i, j, i, j, i, j);
				}
			}
			
			for (i = starting_row; i <= ending_row; ++i) {
				for (j = starting_column; j <= ending_column; ++j) {
					fprintf(filebk, "\t|| inside_%d_%d::[Signal]{1}\n", i, j);
				}
			}
			fprintf(filebk, "end");
		}
		else if (mode == LIST_MODE) {
			fprintf(filebk, "bio\n\nlocalities:\nlogical self;\nlogical next;\n");
			for (i = 0; i < rows; ++i) {
				for (j = 0; j < columns; ++j) {
					fprintf(filebk, "physical inside_%d_%d;\nphysical outside_%d_%d;\n", i, j, i, j);
				}
			}
			fprintf(filebk, "\nenvironments:\n");
			
			for (i = 0; i < rows; ++i) {
				for (j = 0; j < columns; ++j) {
					if (i == (rows - 1)) {
						fprintf(filebk, "inside_%d_%d: [self -> inside_%d_%d];\n", i, j, i, j);
						continue;
					}
					fprintf(filebk, "inside_%d_%d: [self -> inside_%d_%d, next -> inside_%d_%d];\n", i, j, i, j, i+1, j);
				}
			}
			
			fprintf(filebk, "\nmessages: Na, K, Signal, NaChan, KChan, Pump, Ddp, Ready, Ignore;\n\nagents:\n");
			
			for (i = 0; i < rows; ++i) {
				for (j = 0; j < columns; ++j) {
					if (i == (rows - 1)) {
						fprintf(filebk, 
								"let CellAgent_%d_%d be \nX ->  in( Signal )@self:1.0.[NaChan] | [Ignore] | X1 \n \nX1  ->  {[Ignore]@inside_%d_%d => 1.0} in( Signal )@self:1000000000000000.0.X1 \n+   {[NaChan]@inside_%d_%d > 0.0 && (8.314*310.15*ln([Na]@outside_%d_%d / [Na]@inside_%d_%d)) > -(96.485*30)} in( Na )@outside_%d_%d:0.65.[Na] | X1 \n+   {[NaChan]@inside_%d_%d > 0.0 && (8.314*310.15*ln([Na]@outside_%d_%d / [Na]@inside_%d_%d)) <= -(96.485*30)} in( NaChan )@self:10.0.[KChan] | X1 \n+   {[KChan]@inside_%d_%d > 0.0 && (8.314*310.15*ln([K]@outside_%d_%d / [K]@inside_%d_%d)) < (96.485*90)} in( K )@self:10.0.[K]@outside_%d_%d | X1 \n+   {[KChan]@inside_%d_%d > 0.0 && (8.314*310.15*ln([K]@outside_%d_%d / [K]@inside_%d_%d)) => (96.485*90)} in( KChan )@self:0.7.[Pump] | X3 \n \nX3  ->  eval(CellAgent_%d_%d[X4])@self:100000.0.X2 \n \nX4  ->  {[Ignore]@inside_%d_%d => 1.0} in( Signal )@self:1000000000000000.0.X1 \n+   {[Pump]@inside_%d_%d > 0.0 && [Ddp]@inside_%d_%d < 15.0} out( Ddp )@self:100000.0.X4 \n+   {[Pump]@inside_%d_%d <= 0.0} in( Ddp )@self:1.0.X4 \n+   {[Pump]@inside_%d_%d > 0.0 && [Ready]@inside_%d_%d <= 0.0 && [Ddp]@inside_%d_%d => 15.0} out( Ready )@self:10000.0.X4 \n \nX2  ->  {[Ignore]@inside_%d_%d => 1.0} in( Signal )@self:1000000000000000.0.X1 \n+   {[Pump]@inside_%d_%d > 0.0 && [K]@inside_%d_%d < 117.0} in( K )@outside_%d_%d:10000.0.[K]@self | X2 \n+   {[Pump]@inside_%d_%d > 0.0 && [Na]@outside_%d_%d < 63.0} in( Na )@self:10000.0.[Na]@outside_%d_%d | X2 \n+   {[Pump]@inside_%d_%d > 0.0 && [K]@inside_%d_%d => 117.0 && [Na]@outside_%d_%d => 63.0} in( Ignore | Pump | Ready )@self:10000.0.X \n end \n \n", 
								i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j);
						continue;
					}
					fprintf(filebk, 
							"let CellAgent_%d_%d be \nX ->  in( Signal )@self:1.0.[NaChan] | [Ignore] | X1 \n \nX1  ->  {[Ignore]@inside_%d_%d => 1.0} in( Signal )@self:1000000000000000.0.X1 \n+   {[NaChan]@inside_%d_%d > 0.0 && (8.314*310.15*ln([Na]@outside_%d_%d / [Na]@inside_%d_%d)) > -(96.485*30)} in( Na )@outside_%d_%d:0.65.[Na] | X1 \n+   {[NaChan]@inside_%d_%d > 0.0 && (8.314*310.15*ln([Na]@outside_%d_%d / [Na]@inside_%d_%d)) <= -(96.485*30)} in( NaChan )@self:10.0.[KChan] | [Signal]@next | X1 \n+   {[KChan]@inside_%d_%d > 0.0 && (8.314*310.15*ln([K]@outside_%d_%d / [K]@inside_%d_%d)) < (96.485*90)} in( K )@self:10.0.[K]@outside_%d_%d | X1 \n+   {[KChan]@inside_%d_%d > 0.0 && (8.314*310.15*ln([K]@outside_%d_%d / [K]@inside_%d_%d)) => (96.485*90)} in( KChan )@self:0.7.[Pump] | X3 \n \nX3  ->  eval(CellAgent_%d_%d[X4])@self:100000.0.X2 \n \nX4  ->  {[Ignore]@inside_%d_%d => 1.0} in( Signal )@self:1000000000000000.0.X1 \n+   {[Pump]@inside_%d_%d > 0.0 && [Ddp]@inside_%d_%d < 15.0} out( Ddp )@self:100000.0.X4 \n+   {[Pump]@inside_%d_%d <= 0.0} in( Ddp )@self:1.0.X4 \n+   {[Pump]@inside_%d_%d > 0.0 && [Ready]@inside_%d_%d <= 0.0 && [Ddp]@inside_%d_%d => 15.0} out( Ready )@self:10000.0.X4 \n \nX2  ->  {[Ignore]@inside_%d_%d => 1.0} in( Signal )@self:1000000000000000.0.X1 \n+   {[Pump]@inside_%d_%d > 0.0 && [K]@inside_%d_%d < 117.0} in( K )@outside_%d_%d:10000.0.[K]@self | X2 \n+   {[Pump]@inside_%d_%d > 0.0 && [Na]@outside_%d_%d < 63.0} in( Na )@self:10000.0.[Na]@outside_%d_%d | X2 \n+   {[Pump]@inside_%d_%d > 0.0 && [K]@inside_%d_%d => 117.0 && [Na]@outside_%d_%d => 63.0} in( Ignore | Pump | Ready )@self:10000.0.X \n end \n \n", 
							i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j);
				}
			}
			
			fprintf(filebk, "\nsystem:\n");
			
			for (i = 0; i < rows; ++i) {
				for (j = 0; j < columns; ++j) {
					if ((i == (rows - 1)) && (j == (columns - 1))) {
						fprintf(filebk, "\tinside_%d_%d::CellAgent_%d_%d[X]{1} || inside_%d_%d::[K]{117} || outside_%d_%d::[K]{4} || inside_%d_%d::[Na]{20} || outside_%d_%d::[Na]{63} \n", i, j, i, j, i, j, i, j, i, j, i, j, i, j);
						continue;
					}
					fprintf(filebk, "\tinside_%d_%d::CellAgent_%d_%d[X]{1} || inside_%d_%d::[K]{117} || outside_%d_%d::[K]{4} || inside_%d_%d::[Na]{20} || outside_%d_%d::[Na]{63} || \n", i, j, i, j, i, j, i, j, i, j, i, j, i, j);
				}
			}
			
			for (i = starting_row; i <= ending_row; ++i) {
				for (j = 0; j < columns; ++j) {
					fprintf(filebk, "\t|| inside_%d_%d::[Signal]{1}\n", i, j);
				}
			}
			fprintf(filebk, "end");
		}
		fclose(filebk);
	}
	
	filesim = fopen("tessuto.sim", "w");
	
	if ( filesim == NULL) {
		printf("Impossibile aprire/creare il file .sim!");
		exit(1);
	} else if (choice == SIMPLE_CHOICE) {
		for (i = 0; i < rows; ++i) {
			for (j = 0; j < columns; ++j) {
				fprintf(filesim, "Ddp_Cell_%d_%d: [ Ddp ]@cell_%d_%d\n", i, j, i, j);
			}
		}
	}
	else /*Ion Mode*/ {
		for (i = 0; i < rows; ++i) {
			for (j = 0; j < columns; ++j) {
				fprintf(filesim, 
					"\nDdp_Cell_%d_%d: (([NaChan]@inside_%d_%d)*( 105.5908433 - (((8.314*310.15)/(96.485))*ln([Na]@outside_%d_%d / [Na]@inside_%d_%d)))) + (([KChan]@inside_%d_%d)*( 46.0342038592 - (((8.314*310.15)/(96.485))*ln([K]@outside_%d_%d / [K]@inside_%d_%d)) )) + (([Pump]@inside_%d_%d) * (-90 + [Ddp]@inside_%d_%d))\n",
					i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j, i, j);
			}
		}
		fclose(filesim);
	}

    return 0;
}
